package com.company.clientscard.server.reports;

import com.company.clientscard.server.dao.GeneralDao;
import com.company.clientscard.server.service.Context;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.export.JRXlsExporter;
import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
import net.sf.jasperreports.engine.query.JRHibernateQueryExecuterFactory;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@SuppressWarnings("serial")
public class ReportServlet extends HttpServlet {
	private static String REPORT_FILENAME = "reportFilename";
	private static String REPORT_FORMAT = "reportFormat";
	private static String REPORT_DATE1 = "reportDate1";
	private static String REPORT_DATE2 = "reportDate2";
	private static String DEFAULT_REPORTS_SERVICE_PATH = "/reports/";

	private static GeneralDao GENERAL_DAO = Context.getContext().getBean(
			GeneralDao.class);

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.processRequest(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		this.processRequest(req, resp);

	}

	private static Map<String, Object> getParameters() {
		Map<String, Object> parameters = new HashMap<String, Object>();
		parameters.put(
				JRHibernateQueryExecuterFactory.PARAMETER_HIBERNATE_SESSION,
				GENERAL_DAO.getDaoSession());

		return parameters;
	}

	private void showInPDF(InputStream reportStream,
			ServletOutputStream servletOutputStream, Map<String, Object> params)
			throws JRException {
		JasperRunManager.runReportToPdfStream(reportStream,
				servletOutputStream, params);
	}

	private void exportToXls(InputStream reportStream,
			ServletOutputStream servletOutputStream, Map<String, Object> params)
			throws JRException {
		JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream,
				params);
		JRXlsExporter exporter = new JRXlsExporter();
		exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
		exporter.setParameter(JRExporterParameter.OUTPUT_STREAM,
				servletOutputStream);
		exporter.setParameter(JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
				Boolean.TRUE);
		exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,
				Boolean.TRUE);
		exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,
				Boolean.FALSE);
		exporter.setParameter(
				JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,
				Boolean.TRUE);
		exporter.exportReport();
	}

	private void processRequest(HttpServletRequest request,
			HttpServletResponse response) throws ServletException, IOException {

		System.out.println("Servlet started");

		String reportFilename = request.getParameter(REPORT_FILENAME);
		String resourceName = DEFAULT_REPORTS_SERVICE_PATH + reportFilename;

		String reportFormat = request.getParameter(REPORT_FORMAT);

		String reportDate1 = request.getParameter(REPORT_DATE1);
		String reportDate2 = request.getParameter(REPORT_DATE2);

		DateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
		Date date1 = new Date();
		Date date2 = new Date();

		try {
			date1 = dateFormat.parse(reportDate1);
			date2 = dateFormat.parse(reportDate2);
		} catch (ParseException e1) {
			date1 = new Date();
			date2 = new Date();
			e1.printStackTrace();
		}

		ServletContext context = this.getServletConfig().getServletContext();

		ServletOutputStream servletOutputStream = response.getOutputStream();

		try {
			JasperCompileManager.compileReportToFile(
					context.getRealPath(resourceName + ".jrxml"),
					context.getRealPath(resourceName + ".jasper"));

			InputStream reportStream = getServletConfig().getServletContext()
					.getResourceAsStream(resourceName + ".jasper");

			Map<String, Object> params = getParameters();
			params.put("date1", date1);
			params.put("date2", date2);

			if (reportFormat == null) {
				response.setContentType("application/pdf");
				showInPDF(reportStream, servletOutputStream, params);
			} else if (reportFormat.equals("XLS_EXPORT")) {
				response.setContentType("application/vnd.ms-excel");
				exportToXls(reportStream, servletOutputStream, params);
			} else if (reportFormat.equals("SHOW_IN_PDF")) {
				response.setContentType("application/pdf");
				showInPDF(reportStream, servletOutputStream, params);
			} else {
				response.setContentType("application/pdf");
				showInPDF(reportStream, servletOutputStream, params);
			}

		} catch (Exception e) {
			// TODO Auto-generated catch block
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace(printWriter);
			response.setContentType("text/plain");
			response.getOutputStream().print(stringWriter.toString());

		} finally {
            servletOutputStream = null;
//			servletOutputStream.flush();
//			servletOutputStream.close();

		}

	}

}
